﻿// ***********************************************************************
// Assembly         : MVC4Portal
// Author           : Lolo
// Created          : 10-01-2013
//
// Last Modified By : Lolo
// Last Modified On : 10-18-2013
// ***********************************************************************
// <copyright file="AdminController.cs" company="Innovacall">
//     Copyright (c) Innovacall. All rights reserved.
// </copyright>
// <summary></summary>
// ***********************************************************************
using EmitMapper;
using InnovaApp.Layers.DataLayer;
using InnovaApp.Layers.DomainLayer;
using InnovaApp.Layers.ResourcesLayer.Properties;
using InnovaApp.Layers.SecurityLayer.Models.MetaModels;
using InnovaApp.Portals.MVC4Portal.Models.JSonModels;
using InnovaApp.Portals.MVC4Portal.Models.MetaModels.ContactManagement;
using InnovaApp.Portals.MVC4Portal.Models.ViewModels;
using INNOVACALL.Framework.Common.Models;
using INNOVACALL.Framework.Common.MVCHelpers;
using INNOVACALL.Framework.Common.InnovacallExceptions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using System.Transactions;

namespace InnovaApp.Portals.MVC4Portal.Controllers.ViewControllers.LayoutViewControllers.SecurityControllers
{
    /// <summary>
    /// Class AdminController.
    /// </summary>

    public class AdminController : InnovaApp.Layers.CommonLayer.Controllers.ViewControllers._ViewControllers_Base<Admin_ViewModel>
    {
        /// <summary>
        /// Initializes data that might not be available when the constructor is called.
        /// </summary>
        /// <param name="requestContext">The HTTP context and route data.</param>
        protected override void Initialize(System.Web.Routing.RequestContext requestContext)
        {
            base.eMethodBase = "InnovaApp.Portals.InnovaAppFrontOfficePortal.Controllers.DynaStructureController";
            base.Initialize(requestContext);
        }
        #region AdminUsers
        /// <summary>
        /// Users the item feed.
        /// </summary>
        /// <param name="language">The language.</param>
        /// <param name="ajaxModel">The ajax model.</param>
        /// <returns>JsonResult.</returns>
        /// <exception cref="INNOVACALL.Framework.Common.InnovacallExceptions.IdentificationException"></exception>
        /// <exception cref="INNOVACALL.Framework.Common.InnovacallExceptions.DataIntegrityException"></exception>
        [Authorize(Roles = "Admin"), HttpPost, CacheManager(enCacheMode.NoCache)]
        public JsonResult UserItemFeed(string language, AdminUser_JSonModel ajaxModel)
        {
            JsonResult toReturn = new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet };
            AdminUser_ViewModel toGenerateViewModel = new AdminUser_ViewModel();
            string eMethod = eMethodBase + "UserItemFeed[POST]";
            object eParameters = new { ajaxModel = ajaxModel };

            bool success = false;
            string htmlContent = string.Empty;
            string scriptToExecute = string.Empty;
            string messageTitle = string.Empty;
            string message = string.Empty;

            INNOVACALL.Framework.Common.MVCHelpers.Localization.CommonLocalization.SetCurrentThreadLanguage(language);
            MembershipUser UIUser = Membership.GetUser();
            try
            {
                using (DataRepositories _dataContext = new DataRepositories())
                {
                    //Check id requested user is in the current Application
                    InnoAppUser dbInnoAppUser = _dataContext.InnoAppUser_Rep.Query(x => x.Id == (Guid)UIUser.ProviderUserKey).FirstOrDefault();
                    if (dbInnoAppUser == null)
                    {
                        throw new INNOVACALL.Framework.Common.InnovacallExceptions.IdentificationException(eMethod, eParameters, Resources.View_All_UserNotFound);
                    }
                    Guid applicationId = dbInnoAppUser.FK_Application;
                    if (dbInnoAppUser.Id != ajaxModel.Id)
                    {
                        dbInnoAppUser = _dataContext.InnoAppUser_Rep.Query(x => x.Id == ajaxModel.Id).FirstOrDefault();
                        if (dbInnoAppUser == null)
                        {
                            throw new INNOVACALL.Framework.Common.InnovacallExceptions.DataIntegrityException(eMethod, eParameters, Resources.View_AdminUser_RequestedUserNoLongerExists);
                        }
                    }
                    toGenerateViewModel.User = ObjectMapperManager.DefaultInstance.GetMapper<InnoAppUser, InnoAppUser_MetaModel>().Map(dbInnoAppUser);
                    Contact dbContact = _dataContext.Contact_Rep.Query(x => x.FK_InnoAppUser == dbInnoAppUser.Id).FirstOrDefault();
                    if (dbInnoAppUser.Contact != null)
                    {
                        toGenerateViewModel.Contact = ObjectMapperManager.DefaultInstance.GetMapper<Contact, ManagedContact_MetaModel>().Map(dbContact);
                        IEnumerable<Genre> dbGenres = _dataContext.Genre_Rep.GetAll().OrderBy(x => x.SortIndex).AsEnumerable();
                        toGenerateViewModel.Contact.Genres = dbGenres.Select(
                            x => new SelectListItem()
                            {
                                Value = x.Id.ToString(),
                                Text = INNOVACALL.Framework.Common.MVCHelpers.Localization.CommonLocalization.LookupResource(typeof(Resources), x.Name),
                                Selected = x.Id == dbContact.FK_Genre
                            }).ToList();
                        toGenerateViewModel.Contact.Genres.Insert(0, new SelectListItem() { Value = "-1", Text = string.Empty, Selected = dbContact.FK_Genre == null });
                        IEnumerable<Language> dbLanguages = _dataContext.Language_Rep.GetAll().OrderBy(x => x.SortIndex).AsEnumerable();
                        toGenerateViewModel.Contact.Languages = dbLanguages.Select(
                            x => new SelectListItem()
                            {
                                Value = x.Id.ToString(),
                                Text = INNOVACALL.Framework.Common.MVCHelpers.Localization.CommonLocalization.LookupResource(typeof(Resources), "View_All_Languages_" + x.Name),
                                Selected = dbContact.FK_Language == x.Id
                            }).ToList();
                        toGenerateViewModel.Contact.Languages.Insert(0, new SelectListItem() { Value = "-1", Text = string.Empty, Selected = dbContact.FK_Genre == null });
                        //Roles
                        IEnumerable<InnoRole> dbRoles = _dataContext.InnoRole_Rep.GetAll().AsEnumerable();
                        foreach (var r in dbRoles)
                        {
                            bool userInRole = _dataContext.InnoUsersInRoles_Rep.Query(x => x.FK_InnoAppUser == dbInnoAppUser.Id && x.FK_InnoRole == r.Id).Count() > 0;
                            toGenerateViewModel.User.Roles.Add(new CheckBoxListElement() { Value = r.Id.ToString(), Text = r.Name, Selected = userInRole });
                        }
                        success = true;
                        htmlContent = base.RenderPartialViewToString("_AdminUser", toGenerateViewModel);
                        scriptToExecute = string.Empty;
                        messageTitle = string.Empty;
                        message = string.Empty;

                        toReturn.Data = new INNOVACALLAjaxResponse(
                            success: true,
                            domElementToUpdate: ajaxModel.HtmlElementToUpdate,
                            htmlContent: htmlContent,
                            scriptToExecute: scriptToExecute,
                            messageTitle: messageTitle,
                            message: message,
                            additionalData: new { @modelToFeed = toGenerateViewModel, @forUserId = dbInnoAppUser.Id }
                        );
                    }
                }

            }
            catch (Exception ex)
            {
                INNOVACALL.Framework.Common.InnovacallExceptions.CommonException iex = new INNOVACALL.Framework.Common.InnovacallExceptions.CommonException(eMethod, eParameters, ex.Message);
                iex.LogIt();
                toReturn.Data = new INNOVACALLAjaxResponse(
                    success: false,
                    domElementToUpdate: null,
                    htmlContent: null,
                    scriptToExecute: "$.fn.jqDialogAlert(a.messageTitle ,a.message,'');",
                    messageTitle: Resources.View_All_DialogErrorTitle,
                    message: ex.LayoutException(),
                    additionalData: null
                );
            }
            return toReturn;
        }

        /// <summary>
        /// Contacts the user save.
        /// </summary>
        /// <param name="language">The language.</param>
        /// <param name="model">The model.</param>
        /// <returns>JsonResult.</returns>
        /// <exception cref="INNOVACALL.Framework.Common.InnovacallExceptions.IdentificationException"></exception>
        [Authorize(Roles = "Admin"), HttpPost, CacheManager(enCacheMode.NoCache)]
        public JsonResult ContactUserSave(string language, AdminUser_ViewModel model)
        {
            JsonResult toReturn = new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet };
            AdminUser_ViewModel toGenerateViewModel = new AdminUser_ViewModel();
            string eMethod = eMethodBase + "SaveContactUser[POST]";
            object eParameters = new { language = language, model = model };
            object userKey;
            bool notifyLoginChange = false;
            bool notifyEMailChange = false;
            using (TransactionScope _ts = new TransactionScope())
            {
                try
                {
                    using (DataRepositories _dataContext = new DataRepositories())
                    {
                        Contact dbContact = _dataContext.Contact_Rep.Query(m => m.Id == model.Contact.Id && m.InnoAppUser.Id == model.User.Id).FirstOrDefault();
                        if (dbContact == null)
                        {
                            throw new INNOVACALL.Framework.Common.InnovacallExceptions.IdentificationException(eMethod, eParameters, Resources.View_All_UserNotFound);
                        }
                        dbContact.FK_Genre = model.Contact.FK_Genre;
                        dbContact.FirstName = model.Contact.FirstName;
                        dbContact.LastName = model.Contact.LastName;
                        DateTime birthDate;
                        if (DateTime.TryParse(model.Contact.BirthDate.ToString(), out birthDate))
                        {
                            dbContact.BirthDate = birthDate;
                        }
                        dbContact.IconPath = model.Contact.IconPath;
                        dbContact.FK_Language = model.Contact.FK_Language;
                        //ToDo LJO : Decide if google map must be used here
                        //double lat, lng;
                        //if (model.Contact.GoogleMapLat.HasValue && model.Contact.GoogleMapLng.HasValue)
                        //{
                        //    if (double.TryParse(model.Contact.GoogleMapLat.ToString(), NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out lat) && double.TryParse(model.Contact.GoogleMapLng.ToString(), NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out lng))
                        //    {
                        //        dbContact.GoogleMapLat = lat;
                        //        dbContact.GoogleMapLng = lng;
                        //    }
                        //}
                        userKey = dbContact.FK_InnoAppUser;
                        _dataContext.Save();
                        InnoAppUser dbUser = _dataContext.InnoAppUser_Rep.Query(x => x.Id == dbContact.FK_InnoAppUser).FirstOrDefault();
                        dbUser.IsApproved = model.User.IsApproved;
                        if (dbUser.Username != model.User.Username)
                        {
                            notifyLoginChange = true;
                            dbUser.Username = model.User.Username;
                        }
                        if (dbUser.Email != model.User.Email)
                        {
                            notifyEMailChange = true;
                            dbUser.Email = model.User.Email;
                        }
                        _dataContext.Save();
                        if (notifyLoginChange || notifyEMailChange)
                        {
                            //SendNotificationMail
                        }
                        MembershipUser mUser = Membership.GetUser((object)dbUser.Id);
                        if (!model.User.IsLockedOut)
                        {
                            if (dbUser.IsLockedOut)
                            {
                                mUser.UnlockUser();
                                Membership.UpdateUser(mUser);
                            }
                        }
                        IQueryable<Guid> currentRoles = _dataContext.InnoUsersInRoles_Rep.Query(x => x.FK_InnoAppUser == dbContact.FK_InnoAppUser).Select(x => x.FK_InnoRole).AsQueryable();
                        foreach (var role in model.User.Roles)
                        {
                            Guid currentRoleId = Guid.Parse(role.Value);
                            if (role.Selected)
                            {
                                if (!currentRoles.Contains(currentRoleId))
                                {
                                    _dataContext.InnoUsersInRoles_Rep.Add(new InnoUsersInRoles() { FK_InnoAppUser = dbContact.FK_InnoAppUser, FK_InnoRole = currentRoleId });
                                }
                            }
                            else
                            {
                                if (currentRoles.Contains(currentRoleId))
                                {
                                    var joinToRemove = _dataContext.InnoUsersInRoles_Rep.Query(x => x.FK_InnoAppUser == dbUser.Id && x.FK_InnoRole == currentRoleId).FirstOrDefault();
                                    if (joinToRemove != null)
                                    {
                                        _dataContext.InnoUsersInRoles_Rep.Remove(joinToRemove);
                                    }
                                }
                            }
                        }
                        _dataContext.Save();
                    }

                    toReturn.Data = new INNOVACALLAjaxResponse(
                        success: true,
                        domElementToUpdate: null,
                        htmlContent: null,
                        scriptToExecute: "$.fn.jqDialogAlert(a.messageTitle ,a.message,'');",
                        messageTitle: Resources.View_All_Cap_MyPrettyCMS_MessageTitle,
                        message: Resources.View_AdminUser_ChangesSaved,
                        additionalData: null
                    );
                    _ts.Complete();
                    //ToDo LJO : Send notification mails
                }
                catch (Exception ex)
                {
                    _ts.Dispose();
                    INNOVACALL.Framework.Common.InnovacallExceptions.CommonException iex = new INNOVACALL.Framework.Common.InnovacallExceptions.CommonException(eMethod, eParameters, ex.Message);
                    iex.LogIt();
                    toReturn.Data = new INNOVACALLAjaxResponse(
                        success: false,
                        domElementToUpdate: null,
                        htmlContent: null,
                        scriptToExecute: "$.fn.jqDialogAlert(a.messageTitle ,a.message,'');",
                        messageTitle: Resources.View_All_DialogErrorTitle,
                        message: ex.LayoutException(),
                        additionalData: null
                    );
                }
                return toReturn;
            }
        }

        /// <summary>
        /// Deletes the user.
        /// </summary>
        /// <param name="language">The language.</param>
        /// <param name="ajaxModel">The ajax model.</param>
        /// <returns>JsonResult.</returns>
        [Authorize(Roles = "Admin"), HttpPost, CacheManager(enCacheMode.NoCache)]
        public JsonResult ContactUserDelete(string language, AdminUser_JSonModel ajaxModel)
        {
            JsonResult toReturn = new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet };
            AdminUser_ViewModel toGenerateViewModel = new AdminUser_ViewModel();
            string eMethod = eMethodBase + "DeleteContactUser[POST]";
            object eParameters = new { ajaxModel = ajaxModel };
            toReturn.Data = new
            {
                @success = false,
                @HtmlElementToUpdate = string.Empty,
                @htmlContent = string.Empty,
                @scriptToExecute = "$.fn.jqDialogAlert(r.messageTitle,r.message,'');",
                @messageTitle = "ToDo",
                @message = "Not implemented yet"
            }; return toReturn;
        }

        #endregion
        #region AdminRoles

        #endregion
    }
}
